using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace Win32SDK
{
    [Flags]
    public enum SHCNE :uint
    {
        RenameItem = 0x1,
        Create = 0x2,
        Delete = 0x4,
        MkDir = 0x8,
        RmDir = 0x10,
        MediaInserted = 0x20,
        MediaRemoved = 0x40,
        DriveRemoved = 0x80,
        DriveAdd = 0x100,
        NetShare = 0x200,
        NetUnShare = 0x400,
        Attributes = 0x800,
        UpdateDir = 0x1000,
        UpdateItem = 0x2000,
        ServerDisconnect = 0x4000,
        UpdateImage = 0x8000,
        DriveAddGUI = 0x10000,
        RenameFolder = 0x20000,
        FreeSpace = 0x40000,
        AssocChanged = 0x8000000,
        DiskEvents = 0x2381F,
        GlobalEvents = 0xC0581E0,
        AllEvents = 0x7FFFFFFF,
        Interrupt = 0x80000000,
    }
    [Flags]
    public enum SHCNF
    {
        IDList = 0,               //  LPITEMIDLIST
        PathA = 0x1,               // path name
        PrinterA = 0x2,            // printer friendly name
        DWORD = 0x3,               // DWORD
        PathW = 0x5,               // path name
        PrinterW = 0x6,            // printer friendly name
        Type = 0xFF,

        Flush = 0x1000,

        FlushNoWait = 0x2000,
        Path = PathW,
        Printer = PrinterW,
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct SHNOTIFYSTRUCT
    {
        public IntPtr dwItem1;
        public IntPtr dwItem2;
    }
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct IDLSTRUCT
    {
        public IntPtr pidl;
        [MarshalAs(UnmanagedType.Bool)]
        public bool bWatchSubFolders;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct SHChangeNotifyEntry
    {
        public IntPtr pIdl;
        [MarshalAs(UnmanagedType.Bool)]
        public Boolean Recursively;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct CMINVOKECOMMANDINFO
    {
        public int cbSize;				// sizeof(CMINVOKECOMMANDINFO)
        public int fMask;				// any combination of CMIC_MASK_*
        public IntPtr hwnd;				// might be NULL (indicating no owner window)
        public IntPtr lpVerb;			// either a string or MAKEINTRESOURCE(idOffset)
        public IntPtr lpParameters;		// might be NULL (indicating no parameter)
        public IntPtr lpDirectory;		// might be NULL (indicating no specific directory)
        public int nShow;				// one of SW_ values for ShowWindow() API
        public int dwHotKey;
        public IntPtr hIcon;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct CMINVOKECOMMANDINFOEX
    {
        public int cbSize;
        public uint fMask;
        public IntPtr hwnd;
        public IntPtr lpVerb;
        [MarshalAs(UnmanagedType.LPStr)]
        public string lpParameters;
        [MarshalAs(UnmanagedType.LPStr)]
        public string lpDirectory;
        public int nShow;
        public int dwHotKey;
        public IntPtr hIcon;
        [MarshalAs(UnmanagedType.LPStr)]
        public string lpTitle;
        public IntPtr lpVerbW;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string lpParametersW;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string lpDirectoryW;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string lpTitleW;
        public POINT ptInvoke;
    }

    [ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), GuidAttribute("000214e4-0000-0000-c000-000000000046")]
    public interface IContextMenu
    {
        [PreserveSig()]
        Int32 QueryContextMenu(
            IntPtr hmenu,
            uint iMenu,
            uint idCmdFirst,
            uint idCmdLast,
            CMF uFlags);

        [PreserveSig()]
        Int32 InvokeCommand(
            ref CMINVOKECOMMANDINFOEX info);

        [PreserveSig()]
        void GetCommandString(
            int idcmd,
            GetCommandStringInformations uflags,
            int reserved,
            StringBuilder commandstring,
            int cch);
    }

    public enum GetCommandStringInformations
    {
        VERB = 0x00000004,
        HELPTEXT = 0x00000005,
        VALIDATE = 0x00000006,
    }

    [Flags]
    public enum CMF : uint
    {
        NORMAL = 0x00000000,
        DEFAULTONLY = 0x00000001,
        VERBSONLY = 0x00000002,
        EXPLORE = 0x00000004,
        NOVERBS = 0x00000008,
        CANRENAME = 0x00000010,
        NODEFAULT = 0x00000020,
        INCLUDESTATIC = 0x00000040,
        EXTENDEDVERBS = 0x00000100,
        RESERVED = 0xffff0000
    }

    [Flags]
    public enum TPM : uint
    {
        LEFTBUTTON = 0x0000,
        RIGHTBUTTON = 0x0002,
        LEFTALIGN = 0x0000,
        CENTERALIGN = 0x0004,
        RIGHTALIGN = 0x0008,
        TOPALIGN = 0x0000,
        VCENTERALIGN = 0x0010,
        BOTTOMALIGN = 0x0020,
        HORIZONTAL = 0x0000,
        VERTICAL = 0x0040,
        NONOTIFY = 0x0080,
        RETURNCMD = 0x0100,
        RECURSE = 0x0001,
        HORPOSANIMATION = 0x0400,
        HORNEGANIMATION = 0x0800,
        VERPOSANIMATION = 0x1000,
        VERNEGANIMATION = 0x2000,
        NOANIMATION = 0x4000,
        LAYOUTRTL = 0x8000
    }



    [Flags()]
    public enum CSIDL
    {
        ADMINTOOLS = 0x30,
        ALTSTARTUP = 0x1d,
        APPDATA = 0x1a,
        BITBUCKET = 10,
        CDBURN_AREA = 0x3b,
        COMMON_ADMINTOOLS = 0x2f,
        COMMON_ALTSTARTUP = 30,
        COMMON_APPDATA = 0x23,
        COMMON_DESKTOPDIRECTORY = 0x19,
        COMMON_DOCUMENTS = 0x2e,
        COMMON_FAVORITES = 0x1f,
        COMMON_MUSIC = 0x35,
        COMMON_PICTURES = 0x36,
        COMMON_PROGRAMS = 0x17,
        COMMON_STARTMENU = 0x16,
        COMMON_STARTUP = 0x18,
        COMMON_TEMPLATES = 0x2d,
        COMMON_VIDEO = 0x37,
        CONTROLS = 3,
        COOKIES = 0x21,
        DESKTOP = 0,
        DESKTOPDIRECTORY = 0x10,
        DRIVES = 0x11,
        FAVORITES = 6,
        FLAG_CREATE = 0x8000,
        FONTS = 20,
        HISTORY = 0x22,
        INTERNET = 1,
        INTERNET_CACHE = 0x20,
        LOCAL_APPDATA = 0x1c,
        MYDOCUMENTS = 12,
        MYMUSIC = 13,
        MYPICTURES = 0x27,
        MYVIDEO = 14,
        NETHOOD = 0x13,
        NETWORK = 0x12,
        PERSONAL = 5,
        PRINTERS = 4,
        PRINTHOOD = 0x1b,
        PROFILE = 40,
        PROFILES = 0x3e,
        PROGRAM_FILES = 0x26,
        PROGRAM_FILES_COMMON = 0x2b,
        PROGRAMS = 2,
        RECENT = 8,
        SENDTO = 9,
        STARTMENU = 11,
        STARTUP = 7,
        SYSTEM = 0x25,
        TEMPLATES = 0x15,
        WINDOWS = 0x24
    }







    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("000214F2-0000-0000-C000-000000000046")]
    public interface IEnumIDList
    {

        // Retrieves the specified number of item identifiers in the
        // enumeration sequence and advances the current position by
        // the number of items retrieved.
        [PreserveSig()]
        uint Next(
            uint celt,                // Number of elements in the array pointed to by the rgelt parameter.

            out IntPtr rgelt,        // Address of an array of ITEMIDLIST pointers that receives the item
            // identifiers. The implementation must allocate these item identifiers
            // using the Shell's allocator (retrieved by the SHGetMalloc function).
            // The calling application is responsible for freeing the item
            // identifiers using the Shell's allocator.

            out IntPtr pceltFetched    // Address of a value that receives a count of the item identifiers
            // actually returned in rgelt. The count can be smaller than the value
            // specified in the celt parameter. This parameter can be NULL only
            // if celt is one.
            );

        // Skips over the specified number of elements in the enumeration sequence.
        [PreserveSig()]
        uint Skip(
            uint celt                // Number of item identifiers to skip.
            );

        // Returns to the beginning of the enumeration sequence.
        [PreserveSig()]
        uint Reset();

        // Creates a new item enumeration object with the same contents and state as the current one.
        [PreserveSig()]
        uint Clone(
            out IEnumIDList ppenum        // Address of a pointer to the new enumeration object. The calling
            // application must eventually free the new object by calling its Release member function.
            );
    }
    [Flags]
    public enum SHCONTF : uint
    {
        Folders = 0x0020,   // only want folders enumerated (FOLDER)
        NonFolders = 0x0040,   // include non folders
        IncludeHidden = 0x0080,   // show items normally hidden
        InitOnFirstNext = 0x0100,   // allow EnumObject() to return before validating enum
        NetPrintSearch = 0x0200,   // hint that client is looking for printers
        Shareable = 0x0400,   // hint that client is looking sharable resources (remote shares)
        Storage = 0x0800,   // include all items with accessible storage and their ancestors
    }
    [Flags]
    public enum SFGAOF : uint
    {
        CanCopy = 0x1,                // Objects can be copied    (DROPEFFECT_COPY)
        CanMove = 0x2,                // Objects can be moved     (DROPEFFECT_MOVE)
        CanLink = 0x4,                // Objects can be linked    (DROPEFFECT_LINK)
        Storage = 0x00000008,         // supports BindToObject(IID_IStorage)
        CanRename = 0x00000010,         // Objects can be renamed
        CanDelete = 0x00000020,         // Objects can be deleted
        HasPropSheet = 0x00000040,         // Objects have property sheets
        DropTarget = 0x00000100,         // Objects are drop target
        CapabilityMask = 0x00000177,
        Encrypted = 0x00002000,         // object is encrypted (use alt color)
        IsSlow = 0x00004000,         // 'slow' object
        Ghosted = 0x00008000,         // ghosted icon
        Link = 0x00010000,         // Shortcut (link)
        Share = 0x00020000,         // shared
        ReadOnly = 0x00040000,         // read-only
        Hidden = 0x00080000,         // hidden object
        DisplayAttributeMask = 0x000FC000,
        FileSystemAncestor = 0x10000000,         // may contain children with FILESYSTEM
        Folder = 0x20000000,         // support BindToObject(IID_IShellFolder)
        FileSystem = 0x40000000,         // is a win32 file system object (file/folder/root)
        HasSubFolder = 0x80000000,         // may contain children with FOLDER
        ContentMask = 0x80000000,
        Validate = 0x01000000,         // invalidate cached information
        Removable = 0x02000000,         // is this removeable media?
        Compressed = 0x04000000,         // Object is compressed (use alt color)
        Browsable = 0x08000000,         // supports IShellFolder, but only implements CreateViewObject() (non-folder view)
        NonEnumerated = 0x00100000,         // is a non-enumerated object
        NewContent = 0x00200000,         // should show bold in explorer tree
        CanMoniker = 0x00400000,         // defunct
        HasStorage = 0x00400000,         // defunct
        Stream = 0x00400000,         // supports BindToObject(IID_IStream)
        StorageAncestor = 0x00800000,         // may contain children with STORAGE or STREAM
        StorageCapMask = 0x70C50008,         // for determining storage capabilities, ie for open/save semantics
    }
    [StructLayout(LayoutKind.Explicit, Size = 264)]
    public struct STRRET
    {
        [FieldOffset(0)]
        public UInt32 uType;    // One of the STRRET_* values

        [FieldOffset(4)]
        public IntPtr pOleStr;    // must be freed by caller of GetDisplayNameOf

        [FieldOffset(4)]
        public IntPtr pStr;        // NOT USED

        [FieldOffset(4)]
        public UInt32 uOffset;    // Offset into SHITEMID

        [FieldOffset(4)]
        public IntPtr cStr;        // Buffer to fill in (ANSI)
    }
    [Flags]
    public enum SHGNO : uint
    {
        Normal = 0x0000,  // default (display purpose)
        InFolder = 0x0001,  // displayed under a folder (relative)
        ForEditing = 0x1000,  // for in-place editing
        ForAddressBar = 0x4000,  // UI friendly parsing name (remove ugly stuff)
        ForParsing = 0x8000,  // parsing name for ParseDisplayName()
    }
    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("000214E6-0000-0000-C000-000000000046")]
    public interface IShellFolder
    {
        // Translates a file object's or folder's display name into an item
        // identifier list.
        // Return value: error code, if any
        [PreserveSig()]
        uint ParseDisplayName(
            IntPtr hwnd,        // Optional window handle
            IntPtr pbc,         // Optional bind context that controls the
            // parsing operation. This parameter is
            // normally set to NULL.
            [In(), MarshalAs(UnmanagedType.LPWStr)]
    string pszDisplayName,  // Null-terminated UNICODE string with the
            // display name.
            out uint pchEaten,      // Pointer to a ULONG value that receives the
            // number of characters of the
            // display name that was parsed.
            out IntPtr ppidl,       // Pointer to an ITEMIDLIST pointer that receives
            // the item identifier list for
            // the object.
            ref uint pdwAttributes); // Optional parameter that can be used to
        // query for file attributes.
        // this can be values from the SFGAO enum

        // Allows a client to determine the contents of a folder by creating
        // an item identifier enumeration object and returning its
        // IEnumIDList interface.
        // Return value: error code, if any
        [PreserveSig()]
        uint EnumObjects(
            IntPtr hwnd,        // If user input is required to perform the
            // enumeration, this window handle
            // should be used by the enumeration object as
            // the parent window to take
            // user input.
            SHCONTF grfFlags,       // Flags indicating which items to include in the
            // enumeration. For a list
            // of possible values, see the SHCONTF enum.
            out IEnumIDList ppenumIDList);  // Address that receives a pointer to the
        // IEnumIDList interface of the
        // enumeration object created by this method.

        // Retrieves an IShellFolder object for a subfolder.
        // Return value: error code, if any
        [PreserveSig()]
        uint BindToObject(
            IntPtr pidl,        // Address of an ITEMIDLIST structure (PIDL)
            // that identifies the subfolder.
            IntPtr pbc,         // Optional address of an IBindCtx interface on
            // a bind context object to be
            // used during this operation.
            [In()]
    ref Guid riid,      // Identifier of the interface to return.
            //[MarshalAs(UnmanagedType.Interface)]
            out IntPtr ppv);    // Address that receives the interface pointer.

        // Requests a pointer to an object's storage interface.
        // Return value: error code, if any
        [PreserveSig()]
        uint BindToStorage(
            IntPtr pidl,        // Address of an ITEMIDLIST structure that
            // identifies the subfolder relative
            // to its parent folder.
            IntPtr pbc,         // Optional address of an IBindCtx interface on a
            // bind context object to be
            // used during this operation.
            [In()]
    ref Guid riid,      // Interface identifier (IID) of the requested
            // storage interface.
            [MarshalAs(UnmanagedType.Interface)]
    out object ppv);    // Address that receives the interface pointer
        // specified by riid.

        // Determines the relative order of two file objects or folders, given
        // their item identifier lists. Return value: If this method is
        // successful, the CODE field of the HRESULT contains one of the
        // following values (the code can be retrived using the helper function
        // GetHResultCode): Negative A
        // negative return value indicates that the first item should precede
        // the second (pidl1 < pidl2).

        // Positive A positive return value indicates that the first item should
        // follow the second (pidl1 > pidl2).  Zero A return value of zero
        // indicates that the two items are the same (pidl1 = pidl2).
        [PreserveSig()]
        int CompareIDs(
            int lParam,         // Value that specifies how the comparison
            // should be performed. The lower
            // Sixteen bits of lParam define the sorting
            // rule.
            // The upper sixteen bits of
            // lParam are used for flags that modify the
            // sorting rule. values can be from
            // the SHCIDS enum
            IntPtr pidl1,       // Pointer to the first item's ITEMIDLIST
            // structure.
            IntPtr pidl2);      // Pointer to the second item's ITEMIDLIST
        // structure.

        // Requests an object that can be used to obtain information from or interact
        // with a folder object.
        // Return value: error code, if any
        [PreserveSig()]
        uint CreateViewObject(
            IntPtr hwndOwner,       // Handle to the owner window.
            [In()]
    ref Guid riid,      // Identifier of the requested interface.
            [MarshalAs(UnmanagedType.Interface)]
    out object ppv);    // Address of a pointer to the requested
        // interface.

        // Retrieves the attributes of one or more file objects or subfolders.
        // Return value: error code, if any
        [PreserveSig()]
        uint GetAttributesOf(
            int cidl,           // Number of file objects from which to retrieve
            // attributes.
            [In(), MarshalAs(UnmanagedType.LPArray)] IntPtr[]
            apidl,          // Address of an array of pointers to ITEMIDLIST
            // structures, each of which
            // uniquely identifies a file object relative to
            // the parent folder.
            [MarshalAs(UnmanagedType.LPArray)] SFGAOF[]
            rgfInOut);          // Address of a single ULONG value that, on
        // entry,
        // contains the attributes that the caller is
        // requesting. On exit, this value contains the
        // requested attributes that are common to all
        // of the specified objects. this value can
        // be from the SFGAO enum

        // Retrieves an OLE interface that can be used to carry out actions on the
        // specified file objects or folders. Return value: error code, if any
        [PreserveSig()]
        uint GetUIObjectOf(
            IntPtr hwndOwner,       // Handle to the owner window that the client
            // should specify if it displays
            // a dialog box or message box.
            int cidl,           // Number of file objects or subfolders specified
            // in the apidl parameter.
            [In(), MarshalAs(UnmanagedType.LPArray)] IntPtr[]
            apidl,          // Address of an array of pointers to ITEMIDLIST
            // structures, each of which
            // uniquely identifies a file object or subfolder
            // relative to the parent folder.
            [In()]
    ref Guid riid,      // Identifier of the COM interface object to
            // return.
            IntPtr rgfReserved,     // Reserved.
            [MarshalAs(UnmanagedType.Interface)]
     out object ppv);    // Pointer to the requested interface.

        // Retrieves the display name for the specified file object or subfolder.
        // Return value: error code, if any
        [PreserveSig()]
        uint GetDisplayNameOf(
            IntPtr pidl,        // Address of an ITEMIDLIST structure (PIDL)
            // that uniquely identifies the file
            // object or subfolder relative to the parent
            // folder.
            SHGNO uFlags,       // Flags used to request the type of display name
            // to return. For a list of possible values.
            out STRRET pName);      // Address of a STRRET structure in which to
        // return the display name.

        // Sets the display name of a file object or subfolder, changing the item
        // identifier in the process.
        // Return value: error code, if any
        [PreserveSig()]
        uint SetNameOf(
            IntPtr hwnd,        // Handle to the owner window of any dialog or
            // message boxes that the client
            // displays.
            IntPtr pidl,        // Pointer to an ITEMIDLIST structure that
            // uniquely
            // identifies the file object
            // or subfolder relative to the parent folder.
            [In(), MarshalAs(UnmanagedType.LPWStr)]
    string pszName,     // Pointer to a null-terminated string that
            // specifies the new display name.
            SHGNO uFlags,       // Flags indicating the type of name specified by
            // the lpszName parameter. For a list of possible
            // values, see the description of the SHGNO
            // enum.
            out IntPtr ppidlOut);   // Address of a pointer to an ITEMIDLIST
        // structure
        // which receives the new ITEMIDLIST.
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct SHFILEINFO
    {
        public SHFILEINFO(bool b)
        {
            hIcon = IntPtr.Zero;
            iIcon = 0;
            dwAttributes = 0;
            szDisplayName = "";
            szTypeName = "";
        }
        public IntPtr hIcon;
        public int iIcon;
        public uint dwAttributes;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = Constants.MAX_PATH)]
        public string szDisplayName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = Constants.MAX_TYPE)]
        public string szTypeName;
    };

    [Flags]
    public enum SHGFI : int
    {
        /// <summary>get icon</summary>
        Icon = 0x000000100,
        /// <summary>get display name</summary>
        DisplayName = 0x000000200,
        /// <summary>get type name</summary>
        TypeName = 0x000000400,
        /// <summary>get attributes</summary>
        Attributes = 0x000000800,
        /// <summary>get icon location</summary>
        IconLocation = 0x000001000,
        /// <summary>return exe type</summary>
        ExeType = 0x000002000,
        /// <summary>get system icon index</summary>
        SysIconIndex = 0x000004000,
        /// <summary>put a link overlay on icon</summary>
        LinkOverlay = 0x000008000,
        /// <summary>show icon in selected state</summary>
        Selected = 0x000010000,
        /// <summary>get only specified attributes</summary>
        Attr_Specified = 0x000020000,
        /// <summary>get large icon</summary>
        LargeIcon = 0x000000000,
        /// <summary>get small icon</summary>
        SmallIcon = 0x000000001,
        /// <summary>get open icon</summary>
        OpenIcon = 0x000000002,
        /// <summary>get shell size icon</summary>
        ShellIconSize = 0x000000004,
        /// <summary>pszPath is a pidl</summary>
        PIDL = 0x000000008,
        /// <summary>use passed dwFileAttribute</summary>
        UseFileAttributes = 0x000000010,
        /// <summary>apply the appropriate overlays</summary>
        AddOverlays = 0x000000020,
        /// <summary>Get the index of the overlay in the upper 8 bits of the iIcon</summary>
        OverlayIndex = 0x000000040,
    }  
}
